package com.cloud.sso.service;

import com.cloud.sso.common.page.AppPageInfo;
import com.cloud.sso.common.util.CollectionUtil;
import com.cloud.sso.common.util.SnowFlakeUtil;
import com.cloud.sso.dto.*;
import com.cloud.sso.entity.*;
import com.cloud.sso.common.exception.AppException;
import com.cloud.sso.mapper.*;
import com.cloud.sso.vo.RoleVo;
import com.cloud.sso.vo.UserRoleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private ApplicationMapper applicationMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    public List<RoleVo> query(String userId, String appId) {

        if (userId == null || appId == null) {
            throw new AppException("userId或appId不能为空");
        }
        List<SysRole> list = roleMapper.queryUserRoleByApp(userId, appId);

        return entityToVo(list);
    }

    /**
     * 分页查询角色信息
     *
     * @param queryDto
     * @return
     */
    public AppPageInfo query(RoleQueryDto queryDto) {
        queryDto.setStartIndex();

        List<SysRole> roleList = roleMapper.queryRolePage(queryDto);
        Integer count = roleMapper.getCount(queryDto);
        AppPageInfo pageInfo = new AppPageInfo(entityToVo(roleList), count, queryDto.getPageNum(), queryDto.getPageSize());

        return pageInfo;
    }

    public List<SysRoleMenu> queryByRole(String roleId) {
        return roleMenuMapper.queryRoleMenu(roleId);
    }

    /**
     * 保存角色
     *
     * @param roleSaveDto
     */
    @Transactional
    public void save(RoleSaveDto roleSaveDto) {
        try {
            SysRole sysRole = new SysRole();
            BeanUtils.copyProperties(roleSaveDto, sysRole);
            if (roleSaveDto.getId() == null) {
                sysRole.setId(new SnowFlakeUtil().nextStringId());
                roleMapper.insert(sysRole);
            } else {
                roleMapper.updateById(sysRole);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 查询角色详情
     *
     * @param id
     * @return
     */
    public RoleVo get(String id) {
        SysRole sysRole = roleMapper.selectById(id);
        if (sysRole != null) {
            return entityToVo(new ArrayList<SysRole>() {{
                add(sysRole);
            }}).get(0);
        }
        return null;
    }

    /**
     * 删除角色
     *
     * @param id
     */
    public void delete(String id) {
        SysRole sysRole = roleMapper.selectById(id);
        if (sysRole == null) {
            throw new AppException("角色不存在");
        }
        if (CollectionUtil.isNotNull(userRoleMapper.queryByRoleId(id))) {
            throw new AppException("该角色下有授权用户，请先删除授权信息");
        }
        if (CollectionUtil.isNotNull(roleMenuMapper.queryRoleMenu(id))) {
            throw new AppException("该角色下有绑定菜单，请先解绑菜单信息");
        }
        roleMapper.deleteById(id);
    }

    public List<UserRoleVo> queryUserRole(UserRoleQueryDto userRoleDto) {
        List<SysUserRole> userRoles = userRoleMapper.queryUserRole(userRoleDto);
        return entityToUserRoleVo(userRoles);
    }

    public AppPageInfo queryUserRolePage(UserRoleQueryDto userRoleDto) {

        try {
            userRoleDto.setStartIndex();

            List<SysUserRole> userRoleList = userRoleMapper.queryUserRolePage(userRoleDto);
            Integer count = userRoleMapper.getCount(userRoleDto);

            AppPageInfo pageInfo = new AppPageInfo(entityToUserRoleVo(userRoleList), count, userRoleDto.getPageNum(), userRoleDto.getPageSize());


            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AppException(e.getMessage());
        }
    }

    /**
     * 解除用户角色绑定
     *
     * @param roleId
     */
    public void deleteUserRole(String id) {
       userRoleMapper.deleteById(id);
    }


    /**
     * 用户授权
     *
     * @param userRoleDto
     */
    @Transactional
    public void saveUserRole(UserRoleDto userRoleDto) {
        try {
            String userId = userRoleDto.getUserId();

            //重新添加授权数据
            List<RoleOrgDto> roleOrgDtos = userRoleDto.getRoleArray();
            for (RoleOrgDto roleOrgDto : roleOrgDtos) {
                SysUserRole sysUserRole = new SysUserRole();

                sysUserRole.setId(new SnowFlakeUtil().nextStringId());
                sysUserRole.setUserId(userId);

                sysUserRole.setOrgCode(roleOrgDto.getOrgCode());
                sysUserRole.setOrgId(roleOrgDto.getOrgId());
                sysUserRole.setRoleId(roleOrgDto.getRoleId());

                userRoleMapper.insert(sysUserRole);
            }


        } catch (Exception e) {
            e.printStackTrace();
            throw new AppException(e.getMessage());
        }
    }

    /**
     * 角色绑定菜单
     *
     * @param roleMenuSaveDto
     */
    @Transactional
    public void saveRoleMenu(RoleMenuSaveDto roleMenuSaveDto) {
        String roleId = roleMenuSaveDto.getRoleId();

        SysRole sysRole = roleMapper.selectById(roleId);
        if (sysRole == null) {
            throw new AppException("角色不存在");
        }

        //删除原有信息
        roleMenuMapper.deleteRoleMenuByRole(roleMenuSaveDto.getRoleId());

        try {

            for (String menuId : roleMenuSaveDto.getMenuArray()) {
                SysRoleMenu sysRoleMenu = new SysRoleMenu();
                sysRoleMenu.setId(new SnowFlakeUtil().nextStringId());
                sysRoleMenu.setMenuId(menuId);
                sysRoleMenu.setRoleId(roleId);

                roleMenuMapper.insert(sysRoleMenu);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除菜单角色绑定关系
     *
     * @param menuId
     */
    public void deleteRoleMenu(String menuId) {
        roleMenuMapper.deleteByMenu(menuId);
    }

    public List<RoleVo> entityToVo(List<SysRole> roles) {
        List<RoleVo> roleVos = new ArrayList<>();
        if (roles == null) {
            return null;
        }

        roles.stream().forEach(e -> {
            RoleVo roleVo = new RoleVo();
            BeanUtils.copyProperties(e, roleVo);
            Application application = applicationMapper.selectById(e.getAppId());
            roleVo.setAppName(application != null ? application.getAppName() : "");

            roleVos.add(roleVo);
        });

        return roleVos;
    }

    public List<UserRoleVo> entityToUserRoleVo(List<SysUserRole> userRoles) {

        List<UserRoleVo> userRoleVos = new ArrayList<>();
        if (userRoles == null) {
            return null;
        }
        userRoles.stream().forEach(e -> {
            UserRoleVo userRoleVo = new UserRoleVo();
            BeanUtils.copyProperties(e, userRoleVo);


            SysRole sysRole = roleMapper.selectById(e.getRoleId());
            userRoleVo.setRoleName(sysRole != null ? sysRole.getRoleName() : "");


            Application application = applicationMapper.selectById(sysRole.getAppId());
            userRoleVo.setAppName(application != null ? application.getAppName() : "");

            SysOrg sysOrg = orgMapper.selectById(e.getOrgId());
            userRoleVo.setOrgName(sysOrg != null ? sysOrg.getOrgName() : "");

            User user = userMapper.selectById(e.getUserId());
            userRoleVo.setUserName(user.getUserName());
            userRoleVo.setRealName(user.getRealName());

            userRoleVos.add(userRoleVo);
        });

        return userRoleVos;
    }


}
